
package com.plian.system.service.fr.report.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.plian.Tools.*;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.cache.OrgCache;
import com.plian.system.entity.fr.report.ReportColumn;
import com.plian.system.entity.fr.report.ReportColumnValue;
import com.plian.system.entity.fr.report.ReportLink;
import com.plian.system.mapper.fr.report.ReportColumnValueMapper;
import com.plian.system.service.fr.report.IReportColumnService;
import com.plian.system.service.fr.report.IReportColumnValueService;
import com.plian.system.service.fr.report.IReportLinkService;
import com.plian.system.vo.pm.annualdonationrecord.AnnualDonationRecordVO;
import lombok.AllArgsConstructor;
import org.assertj.core.util.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 表格值 服务实现类
 *
 * @author jianglei
 * @since 2019-10-23
 */
@Service
@AllArgsConstructor
public class ReportColumnValueServiceImpl extends ServiceImpl<ReportColumnValueMapper, ReportColumnValue> implements IReportColumnValueService {

    /**
     * logger属性.
     */
    private static final Logger LOGGER  = LoggerFactory.getLogger(ReportColumnValueServiceImpl.class);

    private static final int END_INDEX = 5;

    private static final String TABLE_12 = "ta2021_12";

    private static final String[] LINE_1 = {"对外捐赠支出预算表", "", "", "", "", "", "", ""};

    private static final String[] LINE_2 = {"", "", "", "", "", "", "", "邢国资企预12表"};

    private static final String[] LINE_4 = {"序号", "捐赠单位", "捐赠依据", "受赠对象", "捐赠事由", "捐赠财产构成", "捐赠金额", "捐赠时间"};

    private static final String[] LINE_5 = {"栏次", "1", "2", "3", "4", "5", "6", "7"};

    private static final String[] LINE_LAST = {"    表内公式：6栏合计行=各浮动行之和。　　", "", "", "", "", "", "", ""};

    private static final String[] EMPTY_LINE = {"", "", "", "", "", "", "", ""};

    private static final int TABLE_06_01_START_INDEX = 8;

    private static final String TABLE_06_01_SUM_1 = "自营项目小计";

    private static final String TABLE_06_01_SUM_2 = "政府性项目小计";

    private static final String TABLE_06_01 = "ta2021_06_01";

    private static final String[] TABLE_06_01_LINE_1 = {"年度新增股权投资支出预算表", "", "", "", "", "", "", "", ""};

    private static final String[] TABLE_06_01_LINE_2 = {"", "", "", "", "", "", "", "", "邢国资企预06-1表"};

    private static final String[] TABLE_06_01_LINE_4 = {"序号", "项目名称", "项目性质", "投资企业情况", "", "本年预算支出额", "", "", "备注"};

    private static final String[] TABLE_06_01_LINE_5 = {"", "", "", "名称", "层级(集团为一级）", "本年度支出额", "本年支出完成后，累计完成支出总额", "年末预计持股比例（%）", ""};

    private static final String[] TABLE_06_01_LINE_6 = {"", "栏次", "1", "2", "3", "4", "5", "6", "7"};

    private static final String[] TABLE_06_01_LINE_7 = {"1", "自营项目", "", "", "", "", "", "", ""};

    private static final String[] TABLE_06_01_LINE_15 = {"2", "政府性项目", "", "", "", "", "", "", ""};

    private static final String[] TABLE_06_01_LINE_REMARK_1 = {"注:1.本表所称政府性项目是指经市委常委会、市委财经领导小组、市委全面深化改革领导小组、市政府常务会议、" +
            "市PPP工作领导小组等审议通过，或由市委市政府主要领导、市政府常务副市长主持的专题会议通过或书面确认的投资项目。本表所称自营项目是指企业承担的除政府项目以外的其他投资项目。", "", "", "", "", "", "", "", ""};

    private static final String[] TABLE_06_01_LINE_REMARK_2 = {"2.层级：集团为一级，子公司为二级，依次类推。", "", "", "", "", "", "", "", ""};

    private static final String[] TABLE_06_01_LINE_REMARK_3 = {"3.本年度支出额：反映企业2021年度该项目预计财务支出金额。", "", "", "", "", "", "", "", ""};

    private static final String[] TABLE_06_01_LINE_REMARK_4 = {"4.备注：简要说明项目属于（主业、非主业、培育业务）、内容等事项。合计行=各浮动行之和", "", "", "", "", "", "", "", ""};

    private static final List<String[]> TABLE_06_01_LINE_REMARK_List = Lists.newArrayList(TABLE_06_01_LINE_REMARK_1, TABLE_06_01_LINE_REMARK_2, TABLE_06_01_LINE_REMARK_3, TABLE_06_01_LINE_REMARK_4);

    private static final String[] TABLE_06_01_EMPTY_LINE = {"", "", "", "", "", "", "", "", ""};

    /**
     * 自营项目初始行数
     */
    private static final int TABLE_06_01_TYPE_1_LENGTH = 7;

    /**
     * 政府项目初始行数
     */
    private static final int TABLE_06_01_TYPE_2_LENGTH = 4;


    private static final int TABLE_06_02_START_INDEX = 8;

    private static final String TABLE_06_02_SUM_1 = "自营项目小计";

    private static final String TABLE_06_02_SUM_2 = "政府性项目小计";

    private static final String TABLE_06_02 = "ta2021_06_02";

    private static final String[] TABLE_06_02_LINE_1 = {"年度新增固定资产投资支出预算表", "", "", "", "", "", "", "", "", ""};

    private static final String[] TABLE_06_02_LINE_2 = {"", "", "", "", "", "", "", "", "               邢国资企预06-2表", ""};

    private static final String[] TABLE_06_02_LINE_4 = {"序号", "项目名称", "项目性质", "投资企业情况", "", "是否新开工项目", "已完成财务支出", "", "本年度财务预算支出", "备注"};

    private static final String[] TABLE_06_02_LINE_5 = {"", "", "", "名称", "层级(集团为一级）", "", "其中：上年度实际财务支出", "累计总额", "", ""};

    private static final String[] TABLE_06_02_LINE_6 = {"", "栏次", "1", "2", "3", "4", "5", "6", "7", "8"};

    private static final String[] TABLE_06_02_LINE_7 = {"1", "自营项目", "", "", "", "", "", "", "", ""};

    private static final String[] TABLE_06_02_LINE_12 = {"2", "政府性项目", "", "", "", "", "", "", "", ""};

    private static final String[] TABLE_06_02_LINE_REMARK_1 = {"注:1.本表所称政府性项目是指经市委常委会、市委财经领导小组、市委全面深化改革领导小组、市政府常务会议、市PPP工作领导小组等审议通过，" +
            "或由市委市政府主要领导、市政府常务副市长主持的专题会议通过或书面确认的投资项目。本表所称自营项目是指企业承担的除政府项目以外的其他投资项目。", "", "", "", "", "", "", "", "", ""};

    private static final String[] TABLE_06_02_LINE_REMARK_2 = {"2.层级：集团为一级，子公司为二级，依次类推。", "", "", "", "", "", "", "", "", ""};

    private static final String[] TABLE_06_02_LINE_REMARK_3 = {"3.已完成财务支出：上年度实际财务支出指该项目上个年度实际支出的投资额。" +
            "累计总额：指从项目开工到上年末止，总计已支出的投资额。本年度财务预算支出：指本企业计划在本年度安排的该项固定资产的实际财务支出额。", "", "", "", "", "", "", "", "", ""};

    private static final String[] TABLE_06_02_LINE_REMARK_4 = {"4.备注：简要说明项目属于（主业、非主业、培育业务）、建设内容、新增生产能力或工程效益等事项。合计行=各浮动行之和", "", "", "", "", "", "", "", "", ""};

    private static final String[] TABLE_06_02_EMPTY_LINE = {"", "", "", "", "", "", "", "", "", ""};

    private static final List<String[]> TABLE_06_02_LINE_REMARK_List = Lists.newArrayList(TABLE_06_02_EMPTY_LINE, TABLE_06_02_LINE_REMARK_1, TABLE_06_02_LINE_REMARK_2, TABLE_06_02_LINE_REMARK_3, TABLE_06_02_LINE_REMARK_4);



    /**
     * 自营项目初始行数
     */
    private static final int TABLE_06_02_TYPE_1_LENGTH = 3;

    /**
     * 政府项目初始行数
     */
    private static final int TABLE_06_02_TYPE_2_LENGTH = 3;


    private IReportColumnService reportColumnService;

    private IReportLinkService reportLinkService;


    @Override
    public void initReportValue(String reportId, String orgName, String year, List<AnnualDonationRecordVO> annualDonationRecordVOS) {
        LOGGER.info("------> 对外捐赠支出预算表数据生成  开始");

        List<ReportColumn> reportColumns = reportColumnService.list(new QueryWrapper<ReportColumn>()
                .eq("ORGID", TABLE_12).orderByAsc("COLUMNNAME"));
        ReportLink oldReportLink = reportLinkService.getOne(new QueryWrapper<ReportLink>()
                .eq("ID", reportId).eq("ORGID", TABLE_12));
        String linkId = UuidUtil.get32UUID();
        if (Optional.ofNullable(oldReportLink).isPresent()){
            remove(new QueryWrapper<ReportColumnValue>().eq("LINKID", oldReportLink.getLinkId()));
            linkId = oldReportLink.getLinkId();
        }else {
            ReportLink reportLink = ReportLink.builder().linkId(linkId).orgId(TABLE_12).id(reportId).build();
            reportLinkService.save(reportLink);
        }
        List<ReportColumnValue> reportColumnValues = new ArrayList<>();
        String[] LINE_3 = {"单位:", orgName, "", "年度", year, "", "", "金额单位：万元"};
        List<String[]> initLines = Lists.newArrayList(LINE_1, LINE_2, LINE_3, LINE_4, LINE_5);
        for (int i = 0; i < END_INDEX; i++){
            String[] initLine = initLines.get(i);
            for (int j = 0; j < reportColumns.size(); j++){
                String value = initLine[j];
                String columnId = reportColumns.get(j).getColumnId();
                reportColumnValues.add(ReportColumnValue.builder().columnValueId(UuidUtil.get32UUID())
                        .columnId(columnId).orderNumber(i + 1).linkId(linkId).values(value).replyValue(value).build());
            }
        }

        BigDecimal totalAmount = new BigDecimal(0);
        for (int i = 0; i< annualDonationRecordVOS.size(); i++){
            AnnualDonationRecordVO annualDonationRecordVO  = annualDonationRecordVOS.get(i);
            totalAmount = BigDecimalUtil.add(totalAmount, annualDonationRecordVO.getDonationAmount());
            reportColumnValues.add(ReportColumnValue.builder().columnValueId(UuidUtil.get32UUID())
                    .columnId(reportColumns.get(0).getColumnId()).orderNumber(END_INDEX + i + 2)
                    .linkId(linkId).values("" + (i+1)).replyValue("" + (i+1)).build());
            reportColumnValues.add(ReportColumnValue.builder().columnValueId(UuidUtil.get32UUID())
                    .columnId(reportColumns.get(1).getColumnId()).orderNumber(END_INDEX + i + 2)
                    .linkId(linkId).values(annualDonationRecordVO.getDonationCompanyName())
                    .replyValue(annualDonationRecordVO.getDonationCompanyName()).build());
            reportColumnValues.add(ReportColumnValue.builder().columnValueId(UuidUtil.get32UUID())
                    .columnId(reportColumns.get(2).getColumnId()).orderNumber(END_INDEX + i + 2)
                    .linkId(linkId).values(annualDonationRecordVO.getDonationBasis())
                    .replyValue(annualDonationRecordVO.getDonationBasis()).build());
            reportColumnValues.add(ReportColumnValue.builder().columnValueId(UuidUtil.get32UUID())
                    .columnId(reportColumns.get(3).getColumnId()).orderNumber(END_INDEX + i + 2)
                    .linkId(linkId).values(annualDonationRecordVO.getDonationObject())
                    .replyValue(annualDonationRecordVO.getDonationObject()).build());
            reportColumnValues.add(ReportColumnValue.builder().columnValueId(UuidUtil.get32UUID())
                    .columnId(reportColumns.get(4).getColumnId()).orderNumber(END_INDEX + i + 2)
                    .linkId(linkId).values(annualDonationRecordVO.getDonationCause())
                    .replyValue(annualDonationRecordVO.getDonationCause()).build());
            reportColumnValues.add(ReportColumnValue.builder().columnValueId(UuidUtil.get32UUID())
                    .columnId(reportColumns.get(5).getColumnId()).orderNumber(END_INDEX + i + 2)
                    .linkId(linkId).values(annualDonationRecordVO.getDonationPropertyComposition())
                    .replyValue(annualDonationRecordVO.getDonationPropertyComposition()).build());
            reportColumnValues.add(ReportColumnValue.builder().columnValueId(UuidUtil.get32UUID())
                    .columnId(reportColumns.get(6).getColumnId()).orderNumber(END_INDEX + i + 2)
                    .linkId(linkId).values(BigDecimalUtil.toPlanString(annualDonationRecordVO.getDonationAmount()))
                    .replyValue(BigDecimalUtil.toPlanString(annualDonationRecordVO.getDonationAmount())).build());
            reportColumnValues.add(ReportColumnValue.builder().columnValueId(UuidUtil.get32UUID())
                    .columnId(reportColumns.get(7).getColumnId()).orderNumber(END_INDEX + i + 2)
                    .linkId(linkId).values(annualDonationRecordVO.getDonationTime() != null ?
                    DateUtil.format(annualDonationRecordVO.getDonationTime(), DateUtil.PATTERN_MONTH) : "")
                    .replyValue(annualDonationRecordVO.getDonationTime() != null ?
                            DateUtil.format(annualDonationRecordVO.getDonationTime(), DateUtil.PATTERN_MONTH) :"").build());
        }

        int lastIndex = annualDonationRecordVOS.size() + END_INDEX + 2;

        if (annualDonationRecordVOS.size() < 3){
            for (int i = 0; i < 3 - annualDonationRecordVOS.size(); i++){
                for (int j = 0; j < reportColumns.size(); j++) {
                    reportColumnValues.add(ReportColumnValue.builder().columnValueId(UuidUtil.get32UUID())
                            .columnId(reportColumns.get(j).getColumnId()).orderNumber(lastIndex)
                            .linkId(linkId).values(EMPTY_LINE[j]).replyValue(LINE_LAST[j]).build());
                }
                lastIndex = lastIndex + 1;
            }
        }


        String[] LINE_6 = {"合计", "", "", "", "", "", "=SUM(G" + 7 + ":G" + (lastIndex - 1) + ")", "--"};
        for (int j = 0; j < reportColumns.size(); j++){
            String columnId = reportColumns.get(j).getColumnId();
            reportColumnValues.add(ReportColumnValue.builder().columnValueId(UuidUtil.get32UUID())
                    .columnId(columnId).orderNumber(6).linkId(linkId).values(LINE_6[j]).replyValue(LINE_6[j]).build());
            reportColumnValues.add(ReportColumnValue.builder().columnValueId(UuidUtil.get32UUID())
                    .columnId(columnId).orderNumber(lastIndex).linkId(linkId).values(LINE_LAST[j]).replyValue(LINE_LAST[j]).build());
        }

        lastIndex = lastIndex + 1;
        for (int i = 0; i < 17; i++){
            for (int j = 0; j < reportColumns.size(); j++) {
                reportColumnValues.add(ReportColumnValue.builder().columnValueId(UuidUtil.get32UUID())
                        .columnId(reportColumns.get(j).getColumnId()).orderNumber(lastIndex + i)
                        .linkId(linkId).values(EMPTY_LINE[j]).replyValue(LINE_LAST[j]).build());
            }
        }

        saveBatch(reportColumnValues);
        LOGGER.info("------> 对外捐赠支出预算表数据生成  结束");
    }

    @Override
    public List<PageData> sumTab061(List<String> checkIds) {
        List<ReportLink> reportLinkList = reportLinkService.list(new LambdaQueryWrapper<ReportLink>()
                .in(ReportLink::getId, checkIds).eq(ReportLink::getOrgId, TABLE_06_01));
        List<ReportColumn> reportColumns = reportColumnService.list(new LambdaQueryWrapper<ReportColumn>()
                .eq(ReportColumn::getOrgId, TABLE_06_01).orderByAsc(ReportColumn::getOrderNumber));
        String projectColumn = reportColumns.get(1).getColumnId();
        if (CollectionUtil.isEmpty(reportLinkList)){
            return null;
        }
        List<String> linkIds = reportLinkList.stream().map(ReportLink::getLinkId).collect(Collectors.toList());
        List<ReportColumnValue> reportColumnValues = list(new LambdaQueryWrapper<ReportColumnValue>().in(ReportColumnValue::getLinkId, linkIds));
        if (CollectionUtil.isEmpty(reportColumnValues)){
            return null;
        }
        List<List<ReportColumnValue>> oneList = new ArrayList<>();
        List<List<ReportColumnValue>> twoList = new ArrayList<>();
        String[] TABLE_06_01_LINE_3 = {"单位", OrgCache.orgIdToName(TokenUtil.getTokenOrgId()) , "", "", "", "", "", "", "金额单位：万元"};
        List<String[]> initLines = Lists.newArrayList(TABLE_06_01_LINE_1, TABLE_06_01_LINE_2, TABLE_06_01_LINE_3, TABLE_06_01_LINE_4, TABLE_06_01_LINE_5, TABLE_06_01_LINE_6, TABLE_06_01_LINE_7);

        List<List<ReportColumnValue>> allList = new ArrayList<>();
        for (int i = 0; i < initLines.size(); i++){
            String[] initLine = initLines.get(i);
            List<ReportColumnValue> tempList = initValue(initLine, reportColumns, i + 1);
            allList.add(tempList);
        }

        Map<String, List<ReportColumnValue>> valueLinkIdMap =  reportColumnValues.stream().collect(Collectors.groupingBy(ReportColumnValue::getLinkId));

        valueLinkIdMap.forEach((linkId, valueList) -> {
            Map<Integer, List<ReportColumnValue>> orderNumberMap = valueList.stream().collect(Collectors.groupingBy(ReportColumnValue::getOrderNumber));
            List<Integer> kList  =  orderNumberMap.keySet().stream().sorted().collect(Collectors.toList());
            int sum1Index = 0;
            int sum2Index = 0;
            for (int i = TABLE_06_01_START_INDEX; i <= kList.get(kList.size() - 1); i++){
                List<ReportColumnValue> values = orderNumberMap.get(i);
                boolean flag = false;
                if (sum2Index != 0){
                    break;
                }
                for (ReportColumnValue value : values){
                    if (TABLE_06_01_SUM_1.equals(value.getValues())){
                        sum1Index = i;
                        break;
                    }
                    if (TABLE_06_01_SUM_2.equals(value.getValues())){
                        sum2Index = i;
                        break;
                    }
                    if (projectColumn.equals(value.getColumnId()) &&
                            StringUtil.isNotBlank(StringUtil.cleanChars(value.getValues()))){
                        flag = true;
                        break;
                    }
                }
                if (flag){
                    if (sum1Index == 0){
                        oneList.add(values);
                    }
                    if (sum1Index != 0 && sum2Index == 0 && i > sum1Index + 1){
                        twoList.add(values);
                    }
                }
            }
        });

        int projectIndex = TABLE_06_01_START_INDEX;
        projectIndex = valueListToResults(allList, oneList, reportColumns, projectIndex, TABLE_06_01_TYPE_1_LENGTH, TABLE_06_01_EMPTY_LINE, "1.");
        String[] TABLE_06_01_LINE_SUM_1 = {"", "自营项目小计", "", "", "",
               "=SUM(F8:F" + (projectIndex - 1) + ")", "=SUM(G8:G" + (projectIndex - 1) + ")", "", ""};

        allList.add(initValue(TABLE_06_01_LINE_SUM_1, reportColumns, projectIndex));
        int sum1Index = projectIndex;
        projectIndex++;
        allList.add(initValue(TABLE_06_01_LINE_15, reportColumns, projectIndex));
        projectIndex++;
        int sum2StartIndex = projectIndex;
        projectIndex = valueListToResults(allList, twoList, reportColumns, projectIndex, TABLE_06_01_TYPE_2_LENGTH, TABLE_06_01_EMPTY_LINE, "2.");
        String[] TABLE_06_01_LINE_SUM_2 = {"", "政府性项目小计", "", "", "",
                "=SUM(F" + sum2StartIndex + ":F" + (projectIndex - 1) + ")", "=SUM(G" + sum2StartIndex + ":G" + (projectIndex - 1) + ")", "", ""};
        allList.add(initValue(TABLE_06_01_LINE_SUM_2, reportColumns, projectIndex));
        int sum2Index = projectIndex;
        projectIndex++;
        String[] TABLE_06_01_LINE_TOTAL_SUM = {"合   计", "", "—", "", "",
                "=F" + sum1Index + "+F" + sum2Index, "=G" + sum1Index + "+G" + sum2Index, "", ""};
        allList.add(initValue(TABLE_06_01_LINE_TOTAL_SUM, reportColumns, projectIndex));
        projectIndex++;

        for (int i = 0; i < TABLE_06_01_LINE_REMARK_List.size(); i++){
            String[] initLine = TABLE_06_01_LINE_REMARK_List.get(i);
            allList.add(initValue(initLine, reportColumns, projectIndex));
            projectIndex++;
        }

        return reportColumnValueToPageData(allList, reportColumns);
    }

    @Override
    public List<PageData> sumTab062(List<String> checkIds) {
        List<ReportLink> reportLinkList = reportLinkService.list(new LambdaQueryWrapper<ReportLink>()
                .in(ReportLink::getId, checkIds).eq(ReportLink::getOrgId, TABLE_06_02));
        List<ReportColumn> reportColumns = reportColumnService.list(new LambdaQueryWrapper<ReportColumn>()
                .eq(ReportColumn::getOrgId, TABLE_06_02).orderByAsc(ReportColumn::getOrderNumber));
        String projectColumn = reportColumns.get(1).getColumnId();
        if (CollectionUtil.isEmpty(reportLinkList)){
            return null;
        }
        List<String> linkIds = reportLinkList.stream().map(ReportLink::getLinkId).collect(Collectors.toList());
        List<ReportColumnValue> reportColumnValues = list(new LambdaQueryWrapper<ReportColumnValue>().in(ReportColumnValue::getLinkId, linkIds));
        if (CollectionUtil.isEmpty(reportColumnValues)){
            return null;
        }
        List<List<ReportColumnValue>> oneList = new ArrayList<>();
        List<List<ReportColumnValue>> twoList = new ArrayList<>();
        String[] TABLE_06_02_LINE_3 = {"单位", OrgCache.orgIdToName(TokenUtil.getTokenOrgId()) , "", "", "", "", "", "", "", "金额单位：万元"};

        List<String[]> initLines = Lists.newArrayList(TABLE_06_02_LINE_1, TABLE_06_02_LINE_2, TABLE_06_02_LINE_3, TABLE_06_02_LINE_4, TABLE_06_02_LINE_5, TABLE_06_02_LINE_6, TABLE_06_02_LINE_7);

        List<List<ReportColumnValue>> allList = new ArrayList<>();
        for (int i = 0; i < initLines.size(); i++){
            String[] initLine = initLines.get(i);
            List<ReportColumnValue> tempList = initValue(initLine, reportColumns, i + 1);
            allList.add(tempList);
        }

        Map<String, List<ReportColumnValue>> valueLinkIdMap =  reportColumnValues.stream().collect(Collectors.groupingBy(ReportColumnValue::getLinkId));

        valueLinkIdMap.forEach((linkId, valueList) -> {
            Map<Integer, List<ReportColumnValue>> orderNumberMap = valueList.stream().collect(Collectors.groupingBy(ReportColumnValue::getOrderNumber));
            List<Integer> kList  =  orderNumberMap.keySet().stream().sorted().collect(Collectors.toList());
            int sum1Index = 0;
            int sum2Index = 0;
            for (int i = TABLE_06_02_START_INDEX; i <= kList.get(kList.size() - 1); i++){
                List<ReportColumnValue> values = orderNumberMap.get(i);
                boolean flag = false;
                if (sum2Index != 0){
                    break;
                }
                for (ReportColumnValue value : values){
                    if (TABLE_06_02_SUM_1.equals(value.getValues())){
                        sum1Index = i;
                        break;
                    }
                    if (TABLE_06_02_SUM_2.equals(value.getValues())){
                        sum2Index = i;
                        break;
                    }
                    if (projectColumn.equals(value.getColumnId()) &&
                            StringUtil.isNotBlank(StringUtil.cleanChars(value.getValues()))){
                        flag = true;
                        break;
                    }
                }
                if (flag){
                    if (sum1Index == 0){
                        oneList.add(values);
                    }
                    if (sum1Index != 0 && sum2Index == 0 && i > sum1Index + 1){
                        twoList.add(values);
                    }
                }
            }
        });

        int projectIndex = TABLE_06_02_START_INDEX;
        projectIndex = valueListToResults(allList, oneList, reportColumns, projectIndex, TABLE_06_02_TYPE_1_LENGTH, TABLE_06_02_EMPTY_LINE, "1.");
        String[] TABLE_06_02_LINE_SUM_1 = {"", "自营项目小计", "", "", "", "", "=SUM(G8:G" + (projectIndex - 1) + ")", "=SUM(H8:H" + (projectIndex - 1) + ")", "=SUM(I8:I" + (projectIndex - 1) + ")", ""};


        allList.add(initValue(TABLE_06_02_LINE_SUM_1, reportColumns, projectIndex));
        int sum1Index = projectIndex;
        projectIndex++;
        allList.add(initValue(TABLE_06_02_LINE_12, reportColumns, projectIndex));
        projectIndex++;
        int sum2StartIndex = projectIndex;
        projectIndex = valueListToResults(allList, twoList, reportColumns, projectIndex, TABLE_06_02_TYPE_2_LENGTH, TABLE_06_02_EMPTY_LINE, "2.");
        String[] TABLE_06_02_LINE_SUM_2 = {"", "政府性项目小计", "", "", "", "", "=SUM(G" + sum2StartIndex + ":G" + (projectIndex - 1) + ")",
                "=SUM(H" + sum2StartIndex + ":H" + (projectIndex - 1) + ")", "=SUM(I" + sum2StartIndex + ":I" + (projectIndex - 1) + ")", ""};
        allList.add(initValue(TABLE_06_02_LINE_SUM_2, reportColumns, projectIndex));
        int sum2Index = projectIndex;
        projectIndex++;
        String[] TABLE_06_02_LINE_TOTAL_SUM = {"合计", "", "", "", "", "", "=G" + sum1Index + "+G" + sum2Index, "=H" + sum1Index + "+H" + sum2Index, "=I" + sum1Index + "+I" + sum2Index, ""};
        allList.add(initValue(TABLE_06_02_LINE_TOTAL_SUM, reportColumns, projectIndex));
        projectIndex++;

        for (int i = 0; i < TABLE_06_02_LINE_REMARK_List.size(); i++){
            String[] initLine = TABLE_06_02_LINE_REMARK_List.get(i);
            List<ReportColumnValue> tempList = initValue(initLine, reportColumns, projectIndex);
            allList.add(tempList);
            projectIndex++;
        }

        return reportColumnValueToPageData(allList, reportColumns);
    }

    private static final String[] TABLE_15_LINE_1 = {"房地产项目预算表", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""};

    private static final String[] TABLE_15_LINE_2 = {"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "邢国资企预15表", "", ""};

    private static final String[] TABLE_15_LINE_4 = {"序号", "项目名称", "投资主体名称", "国有股权比例（%）", "投资主体级次", "开工时间", "竣工时间", "计划总投资", "土地开发面积（㎡）", "  房屋新开工面积（㎡）", "", "", "  房屋竣工面积（㎡）", "", "", "  房屋预售", "", "", "", "", "", "  房屋销售结算 ", "", "", "", "", ""};

    private static final String[] TABLE_15_LINE_5 = {"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "房屋预售面积（㎡）", "", "", "房屋预售金额", "", "", "房屋销售结算面积（㎡）", "", "", "房屋销售结算金额 ", "", ""};

    private static final String[] TABLE_15_LINE_6 = {"", "", "", "", "", "", "", "", "", "上年实际数", "本年预算数", "本年比上年增减率(%)", "上年实际数", "本年预算数", "本年比上年增减率(%)", "上年实际数", "本年预算数", "本年比上年增减率(%)", "上年实际数", "本年预算数", "本年比上年增减率(%)", "上年实际数", "本年预算数", "本年比上年增减率(%)", "上年实际数", "本年预算数", "本年比上年增减率(%)"};

    private static final String[] TABLE_15_LINE_7 = {"栏次", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26"};

    private static final String[] TABLE_15_REMARK_LINE_1 = {"表内公式：11栏=（10-9）栏/9栏×100%；14栏=（13-12）栏/12栏×100%；17栏=（16-15）栏/15栏×100%；20栏=（19-18）栏/18栏×100%；", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""};

    private static final String[] TABLE_15_REMARK_LINE_2 = {"23栏=（22-21）栏/21栏×100%；26栏=（25-24）栏/24栏×100%；合计行=各浮动行之和。", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""};

    private static final List<String[]> TABLE_15_LINE_REMARK_List = Stream.of(TABLE_15_REMARK_LINE_1, TABLE_15_REMARK_LINE_2).collect(Collectors.toList());

    private static final String[] TABLE_15_01_EMPTY_LINE = {"", "" , "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""};

    private static final String TABLE_15 = "ta2021_15";

    private static final int TABLE_15_START_INDEX = 8;

    @Override
    public List<PageData> sumTab15(List<String> checkIds) {
        String[] LINE3 = {"单位：", OrgCache.orgIdToName(TokenUtil.getTokenOrgId()) , "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""};

        List<ReportLink> reportLinkList = reportLinkService.list(new LambdaQueryWrapper<ReportLink>()
                .in(ReportLink::getId, checkIds).eq(ReportLink::getOrgId, TABLE_15));
        List<ReportColumn> reportColumns = reportColumnService.list(new LambdaQueryWrapper<ReportColumn>()
                .eq(ReportColumn::getOrgId, TABLE_15).orderByAsc(ReportColumn::getOrderNumber));
        String projectColumn = reportColumns.get(1).getColumnId();
        if (CollectionUtil.isEmpty(reportLinkList)){
            return null;
        }
        List<String> linkIds = reportLinkList.stream().map(ReportLink::getLinkId).collect(Collectors.toList());
        List<ReportColumnValue> reportColumnValues = list(new LambdaQueryWrapper<ReportColumnValue>().in(ReportColumnValue::getLinkId, linkIds));
        if (CollectionUtil.isEmpty(reportColumnValues)){
            return null;
        }
        List<String[]> initLines = Lists.newArrayList(TABLE_15_LINE_1, TABLE_15_LINE_2, LINE3, TABLE_15_LINE_4, TABLE_15_LINE_5, TABLE_15_LINE_6, TABLE_15_LINE_7);
        List<List<ReportColumnValue>> allList = new ArrayList<>();
        for (int i = 0; i < initLines.size(); i++){
            String[] initLine = initLines.get(i);
            List<ReportColumnValue> tempList = initValue(initLine, reportColumns, i + 1);
            allList.add(tempList);
        }

        Map<String, List<ReportColumnValue>> valueLinkIdMap =  reportColumnValues.stream().collect(Collectors.groupingBy(ReportColumnValue::getLinkId));
        List<List<ReportColumnValue>> tempValueList = new ArrayList<>();
        valueLinkIdMap.forEach((linkId, valueList) -> {
            Map<Integer, List<ReportColumnValue>> orderNumberMap = valueList.stream().collect(Collectors.groupingBy(ReportColumnValue::getOrderNumber));
            List<Integer> kList = orderNumberMap.keySet().stream().sorted().collect(Collectors.toList());
            for (int i = TABLE_15_START_INDEX; i <= kList.get(kList.size() - 1); i++) {
                List<ReportColumnValue> values = orderNumberMap.get(i);
                boolean flag = false;
                for (ReportColumnValue value : values){
                    if (projectColumn.equals(value.getColumnId()) &&
                            StringUtil.isNotBlank(StringUtil.cleanChars(value.getValues()))){
                        if (!value.getValues().equals(StringPool.SLASH)){
                            flag = true;
                        }
                        break;
                    }
                }
                if (flag){
                    tempValueList.add(values);
                }
            }
        });

        //公式
        List<String> formulaList = Stream.of(reportColumns.get(11).getColumnId(), reportColumns.get(14).getColumnId(),
                reportColumns.get(17).getColumnId(), reportColumns.get(20).getColumnId(),
                reportColumns.get(23).getColumnId(), reportColumns.get(26).getColumnId()).collect(Collectors.toList());

        if(CollectionUtil.isNotEmpty(tempValueList)){
            for (int i = 0; i < tempValueList.size(); i++){
                int index = 8 + i;
                for (ReportColumnValue value : tempValueList.get(i)){
                    value.setOrderNumber(index);
                    if (formulaList.contains(value.getColumnId())){
                        if (value.getValues().startsWith("=IFERROR((K")){
                            value.setValues("=IFERROR((K" + index + "/J" + index +"-1)*100,)");
                        }
                        if (value.getValues().startsWith("=IFERROR((N")){
                            value.setValues("=IFERROR((N" + index + "/M" + index +"-1)*100,)");
                        }
                        if (value.getValues().startsWith("=IFERROR((Q")){
                            value.setValues("=IFERROR((Q" + index + "/P" + index +"-1)*100,)");
                        }
                        if (value.getValues().startsWith("=IFERROR((T")){
                            value.setValues("=IFERROR((T" + index + "/S" + index +"-1)*100,)");
                        }
                        if (value.getValues().startsWith("=IFERROR((W")){
                            value.setValues("=IFERROR((W" + index + "/V" + index +"-1)*100,)");
                        }
                    }
                }
            }
        }
        int lastIndex = 7 + tempValueList.size();
        int totalIndex = 8 + tempValueList.size();
        if (tempValueList.size()<3){
            lastIndex = 10;
            totalIndex = 11;
            int tempSize = CollectionUtil.isEmpty(tempValueList) ? 0 : tempValueList.size();
            for (int i = 0; i < 3 - tempSize; i++) {
                int index = (CollectionUtil.isEmpty(tempValueList) ? 0 : tempValueList.size()) + i + 8;
                List<ReportColumnValue> tempList = initValue(TABLE_15_01_EMPTY_LINE, reportColumns, index);
                tempValueList.add(tempList);
            }
        }
        allList.addAll(tempValueList);
        String[] TOTAL_LINE = {"合计", "/", "/", "/", "/", "/", "/", "=SUM(H8:H" + lastIndex + ")",
                "=SUM(I8:I" + lastIndex + ")", "=SUM(J8:J" + lastIndex + ")", "=SUM(K8:K" + lastIndex + ")",
                "=IFERROR((K" + totalIndex + "/J" + totalIndex + "-1)*100,)", "=SUM(M8:M" + lastIndex + ")", "=SUM(N8:N" + lastIndex + ")",
                "=IFERROR((N" + totalIndex + "/M" + totalIndex + "-1)*100,)", "=SUM(P8:P" + lastIndex + ")", "=SUM(Q8:Q" + lastIndex + ")",
                "=IFERROR((Q" + totalIndex + "/P" + totalIndex + "-1)*100,)", "=SUM(S8:S" + lastIndex + ")", "=SUM(T8:T" + lastIndex + ")",
                "=IFERROR((T" + totalIndex + "/S" + totalIndex + "-1)*100,)", "=SUM(V8:V" + lastIndex + ")", "=SUM(W8:W" + lastIndex + ")",
                "=IFERROR((W" + totalIndex + "/V" + totalIndex + "-1)*100,)", "=SUM(Y8:Y" + lastIndex + ")", "=SUM(Z8:Z" + lastIndex + ")",
                "=IFERROR((Z" + totalIndex + "/Y" + totalIndex + "-1)*100,)"};

        allList.add(initValue(TOTAL_LINE, reportColumns, totalIndex));
        totalIndex++;
        for (int i = 0; i < TABLE_15_LINE_REMARK_List.size(); i++){
            String[] initLine = TABLE_15_LINE_REMARK_List.get(i);
            allList.add(initValue(initLine, reportColumns, totalIndex));
            totalIndex++;
        }

        return reportColumnValueToPageData(allList, reportColumns);
    }

    @Override
    public ReportColumnValue findValueByLinkId(String linkId, int lineNumber, String columnId) {
        return getOne(Wrappers.<ReportColumnValue>lambdaQuery().eq(ReportColumnValue::getLinkId, linkId)
                .eq(ReportColumnValue::getOrderNumber, lineNumber)
                .eq(ReportColumnValue::getColumnId, columnId)
                .orderByAsc(ReportColumnValue::getOrderNumber));
    }

    private int valueListToResults(List<List<ReportColumnValue>> allList, List<List<ReportColumnValue>> list,
                                  List<ReportColumn> reportColumns, int projectIndex, int initialLength, String[] emptyLine, String startIndex){
        if (CollectionUtil.isNotEmpty(list)){
            String indexColumnId = reportColumns.get(0).getColumnId();
            int index = 1;
            for (List<ReportColumnValue> valueList : list){
                for (ReportColumnValue value : valueList){
                    if (indexColumnId.equals(value.getColumnId())){
                        value.setValues(startIndex + index);
                        value.setReplyValue(value.getValues());
                    }
                    value.setColumnValueId(null);
                    value.setLinkId(null);
                    value.setOrderNumber(projectIndex);
                }
                index++;
                allList.add(valueList);
                projectIndex++;
            }
        }

        if (CollectionUtil.isEmpty(list) || list.size() < initialLength) {
            for (int i = 0; i < initialLength - (CollectionUtil.isEmpty(list) ? 0 : list.size()); i++) {
                List<ReportColumnValue> tempList = initValue(emptyLine, reportColumns, projectIndex);
                allList.add(tempList);
                projectIndex++;
            }
        }
        return projectIndex;
    }

    private List<ReportColumnValue> initValue(String[] values, List<ReportColumn> reportColumns, int orderNumber){
        List<ReportColumnValue> reportColumnValueList = new ArrayList<>();
        for (int j = 0; j < reportColumns.size(); j++){
            String value = values[j];
            String columnId = reportColumns.get(j).getColumnId();
            reportColumnValueList.add(ReportColumnValue.builder().columnId(columnId)
                    .orderNumber(orderNumber).values(value).replyValue(value).build());
        }
        return reportColumnValueList;
    }

    private List<PageData> reportColumnValueToPageData(List<List<ReportColumnValue>> list, List<ReportColumn> reportColumns){
        if (CollectionUtil.isEmpty(list)){
            return null;
        }

        List<PageData> pageDataList = new ArrayList<>();
        for (List<ReportColumnValue> reportColumnValues : list){
            Map<String, ReportColumnValue> valueMap = reportColumnValues.stream().collect(Collectors.toMap(ReportColumnValue::getColumnId, value -> value));
            PageData pageData = new PageData();
            pageData.put("ordernumber", reportColumnValues.get(0).getOrderNumber());
            for (int i = 0 ; i < reportColumns.size(); i++){
                pageData.put("c" + i, valueMap.get(reportColumns.get(i).getColumnId()).getValues());
            }
            pageDataList.add(pageData);
        }
        return pageDataList;

    }
}
